package MyFitnessPlate.TestApplication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import MyFitnessPlate.DataSet.ParsedFoodAddDataSet;
import MyFitnessPlate.DataSet.ParsedFoodDataSet;
import MyFitnessPlate.Handler.FoodAddHandler;
import MyFitnessPlate.Handler.FoodHandler;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.ListView;
import android.widget.Spinner;

public class FoodActivity extends Activity {
	
	private int initialDay;
	private int initialMonth;
	private int initialYear;
	
	private ParsedFoodAddDataSet addFoodItem;
	private ArrayList<ParsedFoodDataSet> foodList = new ArrayList<ParsedFoodDataSet>();
	private ArrayList<Integer> foodEntryIdList = new ArrayList<Integer>();
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.food_screen);
        
        final DatePicker datePicker = (DatePicker) findViewById(R.id.dateSelect);
        final Spinner typeSpinner = (Spinner) findViewById(R.id.food_type_spinner);
        final ListView listView = (ListView) findViewById(R.id.listView1);
        final Button addButton = (Button) findViewById(R.id.add_food_button);
        
        //Set the current date.
        Date date = new Date();
        datePicker.init(date.getYear()+1900,date.getMonth(), date.getDate(),new OnDateChangedListener(){
        	public void onDateChanged(DatePicker view, int year, int monthOfYear,int dayOfMonth) {
        	    // Notify the user.
        		if(initialDay != datePicker.getDayOfMonth() ||
				   initialMonth != datePicker.getMonth() ||
				   initialYear != datePicker.getYear()){
					//This will load the entries for a specific date.
					setDateToSelection(datePicker.getDayOfMonth(), datePicker.getMonth(), datePicker.getYear());
					//Now load the feed
					loadFoodEntries();
					loadFeed(listView, typeSpinner.getSelectedItemPosition());
				}
        	}
        });
        
        // Get the day, month, and year from the Date Picker for the URL...
        setDateToSelection(datePicker.getDayOfMonth(), datePicker.getMonth(), datePicker.getYear());
        
        //Initially load the entries for the food.
        loadFoodEntries();
		loadFeed(listView, typeSpinner.getSelectedItemPosition());
        //Get the currently selected type position to add and view items.
        
        //This particular listener changes the food depending on the meal type.
        typeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        	public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { loadFeed(listView, i); }
        	public void onNothingSelected(AdapterView<?> adapterView) { return; }
        });

        //Allow the child elements to be selectable.
        //When the elements are clicked, they will be able to allow a user to delete an item on the list.
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
               public void onItemClick(AdapterView<?> adapterView, View view,int arg2, long arg3) {
            	   final int selectedElement = arg2;
            	   DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            		    public void onClick(DialogInterface dialog, int which) {
            		        switch (which){
            		        case DialogInterface.BUTTON_POSITIVE:
            		            //"yes" action - This will start the method to delete the selected entry-id
            		        	// Once this is done, the food entries will be loaded and the feed will be loaded.
            		        	//Send a message to delete the item on the list.
            		        	try {
            		        		URL url = new URL("http://myfitnessplate.com/api/delete-food-log/entry-id/"+foodEntryIdList.get(selectedElement).intValue()+"/key/HWGCF-YASLT-HOSEC-OZWJH-HETKJ");
            		        		BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            		        		in.close();
            		        		//Notify them of the 
            		        		final AlertDialog alertDialog = new AlertDialog.Builder(FoodActivity.this).create();
                                	alertDialog.setTitle("Deleted");
                                	alertDialog.setMessage("The item has been deleted from the list.");
                                	alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                                		public void onClick(DialogInterface dialog, int which) { alertDialog.dismiss(); }
                                	});
                                	alertDialog.show();
            		        	} catch (MalformedURLException e) {
            		        		handleError("URL error", "URL is incorrect", e);
            		        	} catch (IOException e) {
            		        		handleError("IO error", "Check files", e);
            		        	}
            		        	
            		        	loadFoodEntries();
            		        	loadFeed(listView, typeSpinner.getSelectedItemPosition());
            		        	break;
            		        case DialogInterface.BUTTON_NEGATIVE:
            		            //"no" action - do nothing.
            		        	break;
            		        }
            		    }
            		};
            		final AlertDialog.Builder builder = new AlertDialog.Builder(FoodActivity.this);
            		builder.setMessage("Delete this entry?").setPositiveButton("Yes", dialogClickListener)
            		    .setNegativeButton("No", dialogClickListener).show();
               }
           }
        );
        
        //Create a listener for the add food button. This button should
        //look up food first to see if it is valid. If the food is valid, then it will
        //add it to the currently selected category for that day.
        addButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	EditText addItem = (EditText)findViewById(R.id.add_food_text);
            	if(addItem.getText().toString().trim().equals("")){
            	} else {
            		addFoodItem(addItem.getText().toString().trim());
	            	if(addFoodItem.getSuccess().booleanValue()){
	            		try {
	            			String userName = getParent().getIntent().getExtras().getString("userName");
			        		URL url = new URL("http://myfitnessplate.com/api/new-food-log/username/"+userName+
			        				"/day/"+formatDayMonth(initialDay)+"/month/"+formatDayMonth(initialMonth)+
									  "/year/"+initialYear+"/id/"+addFoodItem.getId()+"/type/"+(typeSpinner.getSelectedItemPosition()+1)+
									  "/key/HWGCF-YASLT-HOSEC-OZWJH-HETKJ");
			        		BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
			        		in.close();
			        		//Notify them of the 
			        		final AlertDialog alertDialog = new AlertDialog.Builder(FoodActivity.this).create();
	                    	alertDialog.setTitle("Added");
	                    	alertDialog.setMessage("The item has been added to the list.");
	                    	alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
	                    		public void onClick(DialogInterface dialog, int which) { alertDialog.dismiss(); }
	                    	});
	                    	alertDialog.show();
	                    	//Now clear the entry.
	                    	addItem.setText("");
			        	} catch (MalformedURLException e) {
			        		handleError("URL error", "URL is incorrect", e);
			        	} catch (IOException e) {
			        		handleError("IO error", "Check files", e);
			        	}
			        	
			        	loadFoodEntries();
			        	loadFeed(listView, typeSpinner.getSelectedItemPosition());
	            	} else {
	            		//Error message.
	            		final AlertDialog alertDialog = new AlertDialog.Builder(FoodActivity.this).create();
	                	alertDialog.setTitle("Error");
	                	alertDialog.setMessage("The item you entered is incorrect or not in our database. Please enter something else.");
	                	alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
	                		public void onClick(DialogInterface dialog, int which) {
	                			alertDialog.dismiss();
	                	    }
	                	});
	                	alertDialog.show();
	            	}
            	}
            }
        });
    }
    
    private void setDateToSelection(int day, int month, int year){
    	initialDay = day; //Day
        initialMonth = month+1; //Month
        initialYear = year; //year
    }
    
    /**
     * This method allows the food entries to be loaded from the web site.
     */
    private void loadFoodEntries(){
    	try {
    		String userName = getParent().getIntent().getExtras().getString("userName");
			URL url = new URL("http://myfitnessplate.com/api/fetch-food-log/username/" + userName +
							  "/day/"+formatDayMonth(initialDay)+"/month/"+formatDayMonth(initialMonth)+
							  "/year/"+initialYear+"/key/HWGCF-YASLT-HOSEC-OZWJH-HETKJ");
			/* Get a SAXParser from the SAXPArserFactory. */
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();
			/* Get the XMLReader of the SAXParser we created. */
			XMLReader xr = sp.getXMLReader();
			/* Create a new ContentHandler and apply it to the XML-Reader */
			FoodHandler myFoodHandler = new FoodHandler();
			xr.setContentHandler(myFoodHandler);
			/* Parse the xml-data from our URL. */
			xr.parse(new InputSource(url.openStream()));
			/* Parsing has finished. */
			/* Our ExampleHandler now provides the parsed data to us. */
			foodList = myFoodHandler.getParsedData();
		} catch (MalformedURLException e) {
			handleError("URL error", "URL is incorrect", e);
		} catch (ParserConfigurationException e) {
			handleError("Parser error", "Check the parser", e);
		} catch (SAXException e) {
			handleError("SAX error", "The SAX parser failed", e);
		} catch (IOException e) {
			handleError("IO error", "Check files", e);
		} finally {}
	}

    private void addFoodItem(String foodItem){
    	try {
    		foodItem = foodItem.replaceAll(" ", "%20");
    		URL url = new URL("http://myfitnessplate.com/api/food-search/name/"+foodItem+
					"/key/HWGCF-YASLT-HOSEC-OZWJH-HETKJ");
    		/* Get a SAXParser from the SAXPArserFactory. */
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();
			/* Get the XMLReader of the SAXParser we created. */
			XMLReader xr = sp.getXMLReader();
			/* Create a new ContentHandler and apply it to the XML-Reader */
			FoodAddHandler myFoodAddHandler = new FoodAddHandler();
			xr.setContentHandler(myFoodAddHandler);
			/* Parse the xml-data from our URL. */
			xr.parse(new InputSource(url.openStream()));
			/* Parsing has finished. */
			/* Our ExampleHandler now provides the parsed data to us. */
			addFoodItem = myFoodAddHandler.getParsedData();
		} catch (MalformedURLException e) {
			handleError("URL error", "URL is incorrect", e);
		} catch (ParserConfigurationException e) {
			handleError("Parser error", "Check the parser", e);
		} catch (SAXException e) {
			handleError("SAX error", "The SAX parser failed", e);
		} catch (IOException e) {
			handleError("IO error", "Check files", e);
		} finally {}
    }
    
    /**
     * This method is used to load the list feed.
     * @param listView
     * @param mealCategory
     */
    private void loadFeed(ListView listView, int mealCategory){
    	try{
	    	//Set up a new list to display the food items.
    		List<String> display = new ArrayList<String>(0);
	    	//Clear the food entry id list so only the new entries will be included.
    		//This is for deleting entries.
	    	foodEntryIdList.clear();
	    	for (ParsedFoodDataSet pfds : foodList){
	    		//This gets the items out of the food data set and displays it. The meal category integer is one lower than the number received. 
	    		if(pfds != null && (mealCategory+1 == pfds.getCategory().intValue())){
	    			display.add(pfds.toString());
	    			foodEntryIdList.add(pfds.getEntry_id());
	    		}
	    	}
	    	ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.fooditem, display);
	    	listView.setAdapter(adapter);
    	} catch (Throwable t){
    		Log.e("Food Item",t.getMessage(),t);
    	}
    }

    /**
     * This method formats the day or month so if the number is less than 10, it has a 0 preceding it.
     * @param dayOrMonth
     * @return
     */
    private String formatDayMonth(int dayOrMonth){
    	if(dayOrMonth < 10){
    		return "0"+dayOrMonth;
    	} else {
    		return ""+dayOrMonth;
    	}
    }
    
    /**
     * This method is used to handle errors by sending the message to the log
     * and printing the exception.
     * @param tag
     * @param message
     * @param e
     */
    private void handleError(String tag, String message, Exception e) {
		Log.d(tag, message);
		e.printStackTrace();
	}
    
    public void onResume(){
    	super.onResume();
    	
    	final Spinner typeSpinner = (Spinner) findViewById(R.id.food_type_spinner);
        final ListView listView = (ListView) findViewById(R.id.listView1);
    	
    	loadFoodEntries();
    	loadFeed(listView, typeSpinner.getSelectedItemPosition());
    }
}